package com.sdjzu.wangfuying.disableautobrightness.aspect;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.SystemClock;
import android.util.Log;

import com.sdjzu.wangfuying.disableautobrightness.service.StatisticsServiceIsNotAService;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

import java.lang.reflect.Method;

@Aspect
@SuppressLint("DefaultLocale")
public class PerformanceAspect {
    private static final String POINT_CUT = "execution(* *(..)) && @annotation(com.sdjzu.wangfuying.disableautobrightness.annotation.Performance)";
    private static final String TAG = "PerformanceAspect";
    // private long startTimestamp = 0L;

    @Pointcut(POINT_CUT)
    public void performance() {

    }

//    @Before(POINT_CUT)
//    public void before(JoinPoint joinPoint) {
//        // startTimestamp = SystemClock.currentThreadTimeMillis();
//    }
//
//    @After(POINT_CUT)
//    public void after(JoinPoint joinPoint) {
//        // System.out.println(String.format("%s: %d", joinPoint.getTarget(), SystemClock.currentThreadTimeMillis() - startTimestamp));
//        System.out.println("after");
//    }

    /**
     * 注意： @Around不能与@Before/@After一起织入，会产生ClassNotFoundException
     *
     * @param point 织入点
     * @throws Throwable proceed()可能抛出的异常
     */
    @Around(POINT_CUT)
    public void around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = SystemClock.currentThreadTimeMillis();
        point.proceed();
        long endTime = SystemClock.currentThreadTimeMillis();
        long consumedTime = endTime - beginTime;
        StatisticsServiceIsNotAService.getInstance().record((int) consumedTime);
        if (System.currentTimeMillis() - StatisticsServiceIsNotAService.getInstance().getLastPersistTimestamp() >= 1000L * 60) {
            Method method = point.getTarget().getClass().getMethod("getBaseContext");
            method.setAccessible(true);
            Context context = (Context) method.invoke(point.getTarget());
            if (!StatisticsServiceIsNotAService.getInstance().isLoaded()) {
                // reload statistics service's data
                StatisticsServiceIsNotAService.getInstance().restore(context);
                // re-record
                StatisticsServiceIsNotAService.getInstance().record((int) consumedTime);
            }
            // persist
            StatisticsServiceIsNotAService.getInstance().persist(context);
        }
        Log.d(TAG, String.format("%s: %d ms", point.getTarget(), consumedTime));
    }
}
